package com.poc.importacao.rios;

import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.poc.importacao.baseabstract.AbstractManager;
import com.poc.importacao.baseabstract.Setup;
import com.poc.log.Log;

public class AfluentesManager extends AbstractManager {

    public static final String SELECT_AFLUENTES_JOIN_LINHA = "select r.codlugar from lugar r, rio2lugar t, linha n where t.corio = '%s' and r.codtipolugar = %s and n.codlugar = r.codlugar and st_intersects(t.geom, n.geom) and not st_equals(t.geom, n.geom)";
    public static final String SELECT_RIO_PRINCIPAL_JOIN_LINHA = "select r.codlugar from lugar r, rio2lugar t, linha n where t.corio = '%s' and r.codtipolugar = %s and n.codlugar = r.codlugar and t.geom = n.geom";

    public static final String SELECT_AFLUENTES_JOIN_MULTILINHA = "select r.codlugar from lugar r, rio2lugar t, multilinha n where t.corio = '%s' and r.codtipolugar = %s and n.codlugar = r.codlugar and st_intersects(t.geom, n.geom) and not st_equals(t.geom, n.geom)";
    public static final String SELECT_RIO_PRINCIPAL_JOIN_MULTILINHA = "select r.codlugar from lugar r, rio2lugar t, multilinha n where t.corio = '%s' and r.codtipolugar = %s and n.codlugar = r.codlugar and t.geom = n.geom";

    public static final String SELECT_CORIO_AFLUENTE_JOIN_LINHA = "select t.corio from rio2lugar t, linha n where t.geom = n.geom and n.codlugar = %s";
    public static final String SELECT_CORIO_AFLUENTE_JOIN_MULTILINHA = "select t.corio from rio2lugar t, multilinha n where t.geom = n.geom and n.codlugar = %s";

    public static final String CORIO_PATTERN = "([0-9]*)_([0-9]*)";

    private List<String> insertClauses = new ArrayList<String>();

    protected Integer getCodLugarRio(String corio) throws SQLException {
	String query = String.format(AfluentesManager.SELECT_RIO_PRINCIPAL_JOIN_LINHA, corio, Setup.getCodigoTipoLugar(Setup.RIO));
	ResultSet resultSet = AbstractManager.getDatabaseManager().execute(query);

	if (!resultSet.next()) {
	    query = String.format(AfluentesManager.SELECT_RIO_PRINCIPAL_JOIN_MULTILINHA, corio, Setup.getCodigoTipoLugar(Setup.RIO));
	    resultSet = AbstractManager.getDatabaseManager().execute(query);
	    resultSet.next();
	}

	return resultSet.getInt(1);
    }

    protected ResultSet getTodosCorios() throws SQLException {
	return AbstractManager.getDatabaseManager().execute("select distinct corio from rio2lugar");
    }

    protected ResultSet getAfluentesDeFromLinha(String corio) throws SQLException {
	String query = String.format(AfluentesManager.SELECT_AFLUENTES_JOIN_LINHA, corio, Setup.getCodigoTipoLugar(Setup.RIO));
	return AbstractManager.getDatabaseManager().execute(query);
    }

    protected ResultSet getAfluentesDeFromMultiLinha(String corio) throws SQLException {
	String query = String.format(AfluentesManager.SELECT_AFLUENTES_JOIN_MULTILINHA, corio, Setup.getCodigoTipoLugar(Setup.RIO));
	return AbstractManager.getDatabaseManager().execute(query);
    }

    public Boolean isAfluente(String corioPrincipal, String codlugarAfluente) throws SQLException {
	String query = String.format(AfluentesManager.SELECT_CORIO_AFLUENTE_JOIN_LINHA, codlugarAfluente);
	ResultSet resultSet = AbstractManager.getDatabaseManager().execute(query);
	String corioAfluente;

	if (!resultSet.next()) {
	    query = String.format(AfluentesManager.SELECT_CORIO_AFLUENTE_JOIN_MULTILINHA, codlugarAfluente);
	    resultSet = AbstractManager.getDatabaseManager().execute(query);
	    resultSet.next();
	}

	corioAfluente = resultSet.getString(1);

	Pattern p = Pattern.compile(AfluentesManager.CORIO_PATTERN);
	Matcher corioAlfuenteMatcher = p.matcher(corioAfluente);
	Matcher corioPrincipalMatcher = p.matcher(corioPrincipal);
	corioAlfuenteMatcher.matches();
	corioPrincipalMatcher.matches();

	boolean b = (!corioAlfuenteMatcher.group(1).equals(corioPrincipalMatcher.group(1)) && corioAlfuenteMatcher.group(1).startsWith(
		corioPrincipalMatcher.group(1)))
		|| (corioAlfuenteMatcher.group(1).equals(corioPrincipalMatcher.group(1)) && corioAlfuenteMatcher.group(2).compareTo(
			corioPrincipalMatcher.group(2)) > 0);

	return b;
    }

    public void createInserts(String fileName) throws SQLException, IOException {

	ResultSet corios = this.getTodosCorios();
	ResultSet afluentes;

	Integer codlugarRioPrincipal;
	String corio;

	Double count = 0.0;
	Log inserts = new Log(fileName);
	inserts.append(Setup.INSERT_CLAUSULA_BASE);
	while (corios.next()) {
	    corio = corios.getString(1);

	    codlugarRioPrincipal = this.getCodLugarRio(corio);
	    afluentes = this.getAfluentesDeFromLinha(corio);

	    Integer codTipoRelacionamentoAfluente = Setup.getCodigoTipoRelacionamento(Setup.RIO, Setup.AFLUENTE, Setup.RIO);
	    while (afluentes.next()) {
		if (this.isAfluente(corio, afluentes.getString(1))) {
		    inserts.append((String.format(Setup.INSERT_RELACIONAMENTO_PARAMS, afluentes.getString(1), codlugarRioPrincipal,
			    codTipoRelacionamentoAfluente)));
		}
	    }

	    afluentes = this.getAfluentesDeFromMultiLinha(corio);

	    while (afluentes.next()) {
		if (this.isAfluente(corio, afluentes.getString(1))) {
		    inserts.append((String.format(Setup.INSERT_RELACIONAMENTO_PARAMS, afluentes.getString(1), codlugarRioPrincipal,
			    codTipoRelacionamentoAfluente)));
		}
	    }

	    count++;
	}
	inserts.close();
	this.finalize();
    }

    public static void main(String[] args) throws SQLException, IOException {
	Setup.init();
	AbstractManager afluentesManager = new AfluentesManager();
	afluentesManager.createInserts("insert_afluentes.sql");

    }

    private void putInsert(String insert) {
	this.insertClauses.add(insert.substring(0, insert.length() - 1));
    }
}
